﻿using System;
using System.Net;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using System.Globalization;
//using System.Diagnostics;
//using System.Threading;

namespace NSMyUtils
{
    class MyUtils
    {
        internal static String GetMode(int Mode)
        {
            if (Mode == CIRCLE) return "Circle";
            if (Mode == ALT_HOLD) return "Alt Hold";
            if (Mode == STABILIZE) return "Stabilize";
            if (Mode == LOITER) return "Loiter";
            if (Mode == AUTO) return "Auto";
            if (Mode == LAND) return "Land";
            if (Mode == TAKEOFF) return "TakeOff";
            if (Mode == RETURNTOLAUNCH) return "ReturnToLaunch";
            if (Mode == UNKNOWN) return "UnKnown";
            return "";
        }
        internal static double ConvertToDouble(String ds)
        {  // in europe they use a comma instead of a decimal point, so MyUtils.ConvertToDouble(String) doesn't work, if there's a decimal point in it.
            double d1, d2;
            string delimStr = ".";
            char[] delimiter = delimStr.ToCharArray();

            delimiter = delimStr.ToCharArray();
            string[] split = ds.Split(delimiter);
            ds = ds.Trim();
            try
            {
                if (split.Length == 1) return Convert.ToDouble(ds);
                if (split.Length == 2)
                {
                    d1 = Convert.ToDouble(split[0]);
                    d2 = 0;
                    double d3 = 0.1;
                    for (int i = 0; i < split[1].Length; i++)
                    {
                        int n = split[1][i];
                        if (n < '0' || n > '9') break;
                        n = n - '0';
                        d2 += (double)n * d3;
                        d3 *= 0.1;
                    }
                    if (ds[0] == '-') return d1 - d2; else return d1 + d2;
                }
            }
            catch
            {
                return -1.0;
            }
            return -1.0;
        }
        internal const int STABILIZE = 0;
        internal const int LOITER = 1;
        internal const int AUTO = 2;
        internal const int LAND = 3;
        internal const int TAKEOFF = 4;
        internal const int RETURNTOLAUNCH = 5;
        internal const int CIRCLE = 6;
        internal const int ALT_HOLD = 7;
        internal const int UNKNOWN = 8;
        internal static int GetMode(String Mode)
        {
            Mode = Mode.ToUpper();
            if (Mode.IndexOf("CIRCLE") >= 0) return CIRCLE;
            if (Mode.IndexOf("ALT_HOLD") >= 0) return ALT_HOLD;
            if (Mode.IndexOf("STABILIZE") >= 0) return STABILIZE;
            if (Mode.IndexOf("LOITER") >= 0) return LOITER;
            if (Mode.IndexOf("AUTO") >= 0) return AUTO;
            if (Mode.IndexOf("LAND") >= 0) return LAND;
            if (Mode.IndexOf("TAKEOFF") >= 0) return TAKEOFF;
            if (Mode.IndexOf("RETURNTOLAUNCH") >= 0) return RETURNTOLAUNCH;
            if (Mode.IndexOf("RTL") >= 0) return RETURNTOLAUNCH;
            if (Mode.IndexOf("UNKNOWN") >= 0) return UNKNOWN;
            return UNKNOWN;
        }



        internal const double PT2 = 6.28318530718;
        internal const double R2H = 3.8197186342054;
        internal const double D2R = 0.01745329251994;
        internal const double R2D = 57.29577951308;
        internal const double Deg2Klicks = 111.3194444444;
        internal const double Klicks2Degs = 0.0089831566;
        internal static String Rads2Timedp(double ts)
        {
            String h, m, s;
            if (ts < 0.0) { ts = 0.0 - ts; h = "-"; }
            else h = "";
            while (ts > PT2) ts -= PT2;

            double hrs = Math.Floor(ts * R2H);
            double mins = Math.Floor(((ts * R2H) - hrs) * 60.0);
            if (mins > 59.99999) { mins = 0.0; hrs += 1.0; }
            double secs = ts * R2H * 60.0 - hrs * 60.0 - mins;
            double secs1 = secs = secs * 60.0;
            secs = Math.Round(secs, 3);
            if (secs >= 60.0)
            {
                mins++;
                if (mins > 59.99999) { mins = 0.0; hrs++; }
                if (hrs >= 24.0) hrs = 0.0;
            }
            if (hrs < 10.0) h = h + "0";
            h = h + Convert.ToString(hrs); h = h + ":";
            if (mins < 10.0) m = "0"; else m = "";
            m = m + Convert.ToString(mins); m = m + ":";
            if (secs < 10.0) s = "0"; else s = "";
            s = s + Convert.ToString(secs);
            if (secs == Math.Floor(secs)) s = s + ".0";
            return h + m + s;
        }
        internal static int GetCurrentTimeZone()
        {
            DateTime ut = new DateTime(); ut = DateTime.UtcNow;
            DateTime nw = new DateTime(); nw = DateTime.Now;
            int tz = ut.Hour - nw.Hour;
            if (GetDaylightSavings()) tz++;
            if (tz > 12) tz = tz - 24;
            if (tz < -12) tz = tz + 24;
            return tz;
        }
        static int TZone = -111;
        internal static String MSecsSince0UTToUT(int mSecsSince)
        {
            double Rads = mSecsSince / 1000.0 / 60.0 / 60.0 / 24.0;
            Rads *= MyUtils.PT2;
            return MyUtils.Rads2Timedp(Rads);
        }

        internal static String MSecsSince0UTToLT(int mSecsSince)
        {
            double Rads = mSecsSince / 1000.0 / 60.0 / 60.0;

            if (TZone < -25)
            {
                TZone = MyUtils.GetCurrentTimeZone();
                if (MyUtils.GetDaylightSavings()) TZone--;
            }
            Rads -= (double)TZone;
            Rads /= 24;
            Rads *= MyUtils.PT2;
            if (Rads < 0.0) Rads += MyUtils.PT2;
            return MyUtils.Rads2Timedp(Rads);
        }

        internal static bool GetDaylightSavings()
        {
            DateTime dss = new DateTime();
            DateTime dse = new DateTime();
            TimeZone tzn = TimeZone.CurrentTimeZone;
            DaylightTime dst = tzn.GetDaylightChanges(DateTime.Now.Year);
            dss = dst.Start;
            dse = dst.End;
            bool rv = DateTime.Now > dss && DateTime.Now < dse;
            return (rv);
        }
        WebBrowser wb = new WebBrowser();
        
        internal class WebRequestGetWebPage
        { 
            public static String GetWebString()
            {
                // Create a request for the URL. 		
                WebRequest request = WebRequest.Create("http://www.siderealtechnology.com/index.htm");

                // If required by the server, set the credentials.
                request.Credentials = CredentialCache.DefaultCredentials;
                
                // Get the response.
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                
                // Display the status.
                String WebString = "";
                WebString+=response.StatusDescription;

                // Get the stream containing content returned by the server.
                Stream dataStream = response.GetResponseStream();
             
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);

                // Read the content.
                string responseFromServer = reader.ReadToEnd();

                reader.Close();
                dataStream.Close();
                response.Close();
                WebString += responseFromServer;
                MessageBox.Show(WebString, "Here's your web content");
                return WebString;
            }
        }

        internal class Gdi32
        {
            internal enum DrawingMode
            {
                R2_BLACK = 1,
                R2_COPYPEN = 13,
                R2_MASKNOTPEN = 3,
                R2_MASKPEN = 9,
                R2_MASKPENNOT = 5,
                R2_MERGENOTPEN = 12,
                R2_MERGEPEN = 15,
                R2_MERGEPENNOT = 14,
                R2_NOP = 11,
                R2_NOT = 6,
                R2_NOTCOPYPEN = 4,
                R2_NOTMASKPEN = 8,
                R2_NOTMERGEPEN = 2,
                R2_NOTXORPEN = 10,
                R2_WHITE = 16,
                R2_XORPEN = 7,
            }

            [DllImport("gdi32.dll")]
            internal static extern bool Rectangle(IntPtr hDC, int left, int top, int right, int bottom);

            [DllImport("gdi32.dll")]
            internal static extern bool Ellipse(IntPtr hDC, int left, int top, int right, int bottom);

            [DllImport("gdi32.dll")]
            internal static extern int SetROP2(IntPtr hDC, int fnDrawMode);

            [DllImport("gdi32.dll")]
            internal static extern bool MoveToEx(IntPtr hDC, int x, int y, ref Point p);

            [DllImport("gdi32.dll")]
            internal static extern bool LineTo(IntPtr hdc, int x, int y);

            [DllImport("gdi32.dll")]
            internal static extern IntPtr CreatePen(int fnPenStyle, int nWidth, int crColor);

            [DllImport("gdi32.dll")]
            internal static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObj);

            [DllImport("gdi32.dll")]
             internal static extern bool DeleteObject(IntPtr hObj);

            [DllImport("gdi32.dll")]
            internal static extern bool SetPixel(IntPtr hdc, int X, int Y, int crColor);
            
            [DllImport("gdi32.dll")]
            internal static extern bool TextOut(IntPtr hdc, int x, int y, char[] lpString, int StrLen);

        }

        /// <summary>
        /// Provides utilities directly accessing the gdi32.dll 
        /// </summary>
        internal class GDI
        {
            private static Object thisLock = new Object();
            static private Point nullPoint = new Point(0, 0);

            // Convert the Argb from .NET to a gdi32 RGB
            static private int ArgbToRGB(int rgb)
            {
                return ((rgb >> 16 & 0x0000FF) | (rgb & 0x00FF00) | (rgb << 16 & 0xFF0000));
            }
            static public void DrawXORRectangle(Graphics graphics, Pen pen, Rectangle rectangle)
            {
                lock (thisLock)
                {
                    IntPtr hDC = graphics.GetHdc();
                    IntPtr hPen = Gdi32.CreatePen(0, (int)pen.Width, ArgbToRGB(pen.Color.ToArgb()));
                    Gdi32.SelectObject(hDC, hPen);
                    Gdi32.SetROP2(hDC, (int)Gdi32.DrawingMode.R2_NOTXORPEN);
                    Gdi32.Rectangle(hDC, rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom);
                    Gdi32.DeleteObject(hPen);
                    graphics.ReleaseHdc(hDC);
                }
            }

            static internal void DrawXORText(Graphics graphics, Pen pen, int x1, int y1, String s)
            {//this doesn't work right!  Sorry!
                lock (thisLock)
                {
                    IntPtr hDC = graphics.GetHdc();
                    int clr = ArgbToRGB(pen.Color.ToArgb());
                    clr = ~clr;
                    clr &= 0xFFFFFF;
                    
                    IntPtr hPen = Gdi32.CreatePen(0, (int)pen.Width, clr);
                    Gdi32.SelectObject(hDC, hPen);
                    Gdi32.SetROP2(hDC, (int)Gdi32.DrawingMode.R2_NOTXORPEN);
                    char[] cs =  s.ToCharArray();
                    Gdi32.TextOut(hDC, x1, y1, cs, s.Length);
                    Gdi32.DeleteObject(hPen);
                    graphics.ReleaseHdc(hDC);
                }
            }

            static internal void DrawXOREllipse(Graphics graphics, Pen pen, int x1, int y1, int x2, int y2)
            {
                lock (thisLock)
                {
                    IntPtr hDC = graphics.GetHdc();
                    int clr = ArgbToRGB(pen.Color.ToArgb());
                    clr = ~clr;
                    clr &= 0xFFFFFF;
                    IntPtr hPen = Gdi32.CreatePen(0, (int)pen.Width, clr);
                    Gdi32.SelectObject(hDC, hPen);
                    Gdi32.SetROP2(hDC, (int)Gdi32.DrawingMode.R2_NOTXORPEN);
                    Gdi32.Ellipse(hDC, x1, y1, x2, y2);
                    Gdi32.DeleteObject(hPen);
                    graphics.ReleaseHdc(hDC);
                }
            }

            static internal void DrawXORLine(Graphics graphics, Pen pen, int x1, int y1, int x2, int y2)
            {
                try
                {
                    lock (thisLock)
                    {
                        IntPtr hDC = graphics.GetHdc();
                        int clr = ArgbToRGB(pen.Color.ToArgb());
                        clr = ~clr;
                        clr &= 0xFFFFFF;
                        IntPtr hPen = Gdi32.CreatePen(0, (int)pen.Width, ArgbToRGB(pen.Color.ToArgb()));
                        Gdi32.SelectObject(hDC, hPen);
                        Gdi32.SetROP2(hDC, (int)Gdi32.DrawingMode.R2_NOTXORPEN);
                        Gdi32.MoveToEx(hDC, x1, y1, ref nullPoint);
                        Gdi32.LineTo(hDC, x2, y2);
                        Gdi32.DeleteObject(hPen);
                        graphics.ReleaseHdc(hDC);
                    }
                }
                catch
                {
                    //                MessageBox.Show("error in DrawXORLine");
                }
            }
            static internal void SetPixel(Graphics graphics, Pen pen, int x1, int y1)
            {
                lock (thisLock)
                {
                    IntPtr hDC = graphics.GetHdc();
                    int clr = ArgbToRGB(pen.Color.ToArgb());
                    Gdi32.SetROP2(hDC, (int)Gdi32.DrawingMode.R2_COPYPEN);
                    Gdi32.SetPixel(hDC, x1, y1, clr);
                    graphics.ReleaseHdc(hDC);
                }
            }

        }

    }
}